-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[ADT] Add C++20-style llvm::identity_cxx20 #164143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ADT] Add C++20-style llvm::identity_cxx20 #164143
Conversation
Currently, our llvm::identity<T> is not quite like std::identity from C++20. Ours is a template struct while std::identity is a non-template struct with templatized operator(). This difference means that we cannot mechanically replace llvm::identity with std::identity when we switch to C++20 in the future. This patch implements llvm::identity_cxx20, which behaves exactly like std::identity. Once this patch lands, I'm planning to migrate users of llvm::identity to the new style. There aren't that many: - 4 instances of SparseSet<...> - 3 instances of SparseMultiSet<...> - about 50 instances of IndexedMap<...>
|
@llvm/pr-subscribers-llvm-adt Author: Kazu Hirata (kazutakahirata) ChangesCurrently, our llvm::identity<T> is not quite like std::identity from This patch implements llvm::identity_cxx20, which behaves exactly like Once this patch lands, I'm planning to migrate users of llvm::identity
Full diff: https://github.com/llvm/llvm-project/pull/164143.diff 2 Files Affected:
diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h
index 273a5cf8aa8ff..0e9bd2d455965 100644
--- a/llvm/include/llvm/ADT/STLForwardCompat.h
+++ b/llvm/include/llvm/ADT/STLForwardCompat.h
@@ -19,6 +19,7 @@
#include <optional>
#include <type_traits>
+#include <utility>
namespace llvm {
@@ -117,6 +118,15 @@ struct detector<std::void_t<Op<Args...>>, Op, Args...> {
template <template <class...> class Op, class... Args>
using is_detected = typename detail::detector<void, Op, Args...>::value_t;
+struct identity_cxx20 // NOLINT(readability-identifier-naming)
+{
+ using is_transparent = void;
+
+ template <typename T> constexpr T &&operator()(T &&self) const noexcept {
+ return std::forward<T>(self);
+ }
+};
+
//===----------------------------------------------------------------------===//
// Features from C++23
//===----------------------------------------------------------------------===//
diff --git a/llvm/unittests/ADT/STLForwardCompatTest.cpp b/llvm/unittests/ADT/STLForwardCompatTest.cpp
index 4a8f53cf72f94..2a97e8d6a552f 100644
--- a/llvm/unittests/ADT/STLForwardCompatTest.cpp
+++ b/llvm/unittests/ADT/STLForwardCompatTest.cpp
@@ -184,4 +184,26 @@ TEST(TransformTest, ToUnderlying) {
static_assert(llvm::to_underlying(E3::B3) == 0);
}
+TEST(STLForwardCompatTest, IdentityCxx20) {
+ llvm::identity_cxx20 identity;
+
+ // Test with an lvalue.
+ int X = 42;
+ int &Y = identity(X);
+ EXPECT_EQ(&X, &Y);
+
+ // Test with a const lvalue.
+ const int CX = 10;
+ const int &CY = identity(CX);
+ EXPECT_EQ(&CX, &CY);
+
+ // Test with an rvalue.
+ EXPECT_EQ(identity(123), 123);
+
+ // Test perfect forwarding.
+ static_assert(std::is_same_v<int &, decltype(identity(X))>);
+ static_assert(std::is_same_v<const int &, decltype(identity(CX))>);
+ static_assert(std::is_same_v<int &&, decltype(identity(int(5)))>);
+}
+
} // namespace
|
Currently, our llvm::identity<T> is not quite like std::identity from C++20. Ours is a template struct while std::identity is a non-template struct with templatized operator(). This difference means that we cannot mechanically replace llvm::identity with std::identity when we switch to C++20 in the future. This patch implements llvm::identity_cxx20, which behaves exactly like std::identity. Once this patch lands, I'm planning to migrate users of llvm::identity to the new style. There aren't that many: - 4 instances of SparseSet<...> - 3 instances of SparseMultiSet<...> - about 50 instances of IndexedMap<...>
Currently, our llvm::identity<T> is not quite like std::identity from C++20. Ours is a template struct while std::identity is a non-template struct with templatized operator(). This difference means that we cannot mechanically replace llvm::identity with std::identity when we switch to C++20 in the future. This patch implements llvm::identity_cxx20, which behaves exactly like std::identity. Once this patch lands, I'm planning to migrate users of llvm::identity to the new style. There aren't that many: - 4 instances of SparseSet<...> - 3 instances of SparseMultiSet<...> - about 50 instances of IndexedMap<...>
Currently, our llvm::identity is not quite like std::identity from
C++20. Ours is a template struct while std::identity is a
non-template struct with templatized operator(). This difference
means that we cannot mechanically replace llvm::identity with
std::identity when we switch to C++20 in the future.
This patch implements llvm::identity_cxx20, which behaves exactly like
std::identity.
Once this patch lands, I'm planning to migrate users of llvm::identity
to the new style. There aren't that many: